package javawdw.util.crypt;

import java.io.InputStream;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

import javawdw.io.BinaryReader;
import javawdw.io.simple.BufferedBinaryReader;

/**
 * MD5计算器<br>
 * 
 * @author David
 * 
 */
public class MD5 {
	private static char[] HEX_DIGIT = "0123456789abcdef".toCharArray();

	/**
	 * 计算字符串的MD5
	 * 
	 * @param str
	 *            给定字符串
	 * @return 返回MD5值
	 */
	public static final String cryptString(String str) {
		MessageDigest md = newMD5MessageDigest();
		byte[] strTemp = str.getBytes();
		md.update(strTemp);
		return md5byteToString(md.digest());
	}

	/**
	 * 计算给定文件的MD5
	 * 
	 * @param in
	 *            给定输入流
	 * @return 返回MD5值
	 */
	public static final String cryptStream(InputStream in) {
		MessageDigest md = newMD5MessageDigest();
		BinaryReader binaryReader = new BufferedBinaryReader(in);
		byte[] buffer = new byte[8192];
		int length = -1;
		while ((length = binaryReader.read(buffer)) != -1) {
			md.update(buffer, 0, length);
		}
		binaryReader.close();
		return md5byteToString(md.digest());
	}

	/**
	 * 构造MD5的MessageDigest
	 * 
	 * @return 返回得到的MessageDigest
	 */
	public static final MessageDigest newMD5MessageDigest() {
		try {
			return MessageDigest.getInstance("MD5");
		} catch (NoSuchAlgorithmException e) {
			e.printStackTrace();
		}
		return null;
	}

	private static final String md5byteToString(byte[] buf) {
		int j = buf.length;
		char cs[] = new char[j * 2];
		for (int i = 0; i < j; i++) {
			byte b = buf[i];
			cs[i * 2] = HEX_DIGIT[b >> 4 & 0xf];
			cs[i * 2 + 1] = HEX_DIGIT[b & 0xf];
		}
		return new String(cs);
	}
}